home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Languguage OS 2
/
Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO
/
a_utils
/
lgrammar
/
src
/
function.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-09-09
|
17KB
|
690 lines
/*************************************************************************/
/*
*
* Filename: functions.c
*
*/
#include "grammar.h"
#include <malloc.h>
#include <math.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/timeb.h>
#include <X11/Intrinsic.h>
/* functions in functions.c:
*
* REGELN *create_rule();
* SYMBOLE *create_node();
* REGELN *init_grammar();
* int count_char_word();
* char *word_to_string();
* int test_dimens();
* int listlength();
* SYMBOLE *delete_wordlist();
* REGELN *delete_grammarlist();
* int klammerung();
* int test_wk();
* double random_number();
*
*/
/*************************************************************************/
/* Function Name: create_rule
* Description: legt neuen Knoten vom Typ REGELN an
* Returns: Pointer auf den neuen Knoten
*/
REGELN *create_rule()
{
REGELN *p;
p = (REGELN *)malloc(sizeof(REGELN));
if (p == NULL)
{
fprintf(stderr, "Kein Speicher mehr frei!\n");
fprintf(stderr, "malloc-Aufruf in create_rule\n");
exit(1);
}
/* Belegung mit Default-Werten */
p->symb = ' ';
p->zusatz = 1;
p->indice = ' ';
p->list = NULL;
p->next = NULL;
return p;
}
/*************************************************************************/
/* Function Name: create_node
* Description: legt neuen Knoten vom Typ SYMBOLE an
* Returns: Pointer auf den neuen Knoten
*/
SYMBOLE *create_node()
{
SYMBOLE *p;
p = (SYMBOLE *)malloc(sizeof(SYMBOLE));
if (p == NULL)
{
fprintf(stderr, "Kein Speicher mehr frei\n");
fprintf(stderr, "malloc-Aufruf in create_node\n");
exit(1);
}
/* Belegung mit Default-Werten */
p->symb = ' ';
p->zusatz = 1;
p->indice = ' ';
p->next = NULL;
return p;
}
/************************************************************************/
/* Function Name: init_grammar
* Description: legt eine Regelliste aus den in einem String
* enthaltenen Zeichen an
* Arguments: str - String, der die Zeichen fuer die Regeln enthaelt
* Returns: Pointer auf Regelliste
*/
REGELN *init_grammar(str)
String str;
{
REGELN *create_rule();
SYMBOLE *create_node();
REGELN *p,
*pneu,
*p_end;
SYMBOLE *qneu,
*q_end;
char c;
int i = 0;
int j; /* laeuft durch Zusatz */
char czusatz[10]; /* Zusatz als einzelne char's */
double dzusatz; /* Zusatz als double */
p = create_rule(); /* Grammatik */
p_end = p; /* Hilfszeiger setzen */
qneu = create_node(); /* 1. Zeichen von Axiom */
p_end->list = qneu;
q_end = qneu;
qneu->symb = str[i++];
/* falls '<' nach gelesenem Zeichen angegeben */
while (str[i] == '<')
{
i++;
if (isdigit(str[i]))
{
j = 0;
while ((c = str[i]) != '>')
{
/* solange nicht '>' */
i++;
czusatz[j++] = c;
}
czusatz[j] = NULL;
dzusatz = atof(czusatz);
qneu->zusatz = dzusatz;
i++;
}
else
{
if (isalpha(str[i]))
{
qneu->indice = str[i];
i += 2;
}
}
} /* Ende von '<>'-Bearbeitung */
while (((c = str[i]) != '\n') && (c != '\0')) /* Axiom nicht beendet */
{
qneu = create_node();
q_end->next = qneu;
q_end = qneu;
qneu->symb = c;
i++;
/* falls '<' nach gelesenem Zeichen angegeben */
while (str[i] == '<')
{
i++;
if (isdigit(str[i]))
{
j = 0;
while ((c = str[i]) != '>')
{
/* solange nicht '>' */
i++;
czusatz[j++] = c;
}
czusatz[j] = NULL;
dzusatz = atof(czusatz);
qneu->zusatz = dzusatz;
i++;
}
else
{
if (isalpha(str[i]))
{
qneu->indice = str[i];
i += 2;
}
}
} /* Ende von '<>'-Bearbeitung */
}
while((c = str[i++]) != '\0') /* String noch nicht abgearbeitet */
{
switch(c)
{
case '\n': /* neue Produktion beginnt */
switch(str[i]) /* naechstes Symbol */
{
case '\0': /* Stringende */
break;
case '\n': /* leere Produktion */
break;
default: /* str[i] ist 1.Symbol von neuer Produktion */
pneu = create_rule(); /* neuer Regelknoten */
p_end->next = pneu; /* Knoten anhaengen */
p_end = pneu;
pneu->symb = str[i++]; /* zugehoerige Werte */
/* falls '<' nach gelesenem Zeichen angegeben */
while (str[i] == '<')
{
i++;
if (isdigit(str[i]))
{
j = 0;
while ((c = str[i++]) != '>')
{
/* solange nicht '>' */
czusatz[j++] = c;
}
czusatz[j] = NULL;
dzusatz = atof(czusatz);
pneu->zusatz = dzusatz;
}
else
{
if (isalpha(str[i]))
{
pneu->indice = str[i];
i += 2;
}
}
} /* Ende von '<>'-Bearbeitung */
while (str[i] == ' ') i++; /* Blanks ueberlesen */
if (str[i] == '=')
{
/* Ableitungszeichen */
i++;
if (str[i] == '<')
{
/* Wahrscheinlichkeitsangabe fuer Regel */
i++;
j = 0;
while ((c = str[i++]) != '>')
{
/* solange nicht '>' */
czusatz[j++] = c;
}
czusatz[j] = NULL;
dzusatz = atof(czusatz);
pneu->zusatz = dzusatz;
}
while (str[i] == ' ') i++; /* Blanks ueberlesen */
qneu = create_node(); /* neuer Symbolknoten */
p_end->list = qneu; /* Knoten anhaengen */
q_end = qneu;
qneu->symb = str[i++]; /* zugehoerige Werte */
/* falls '<' nach gelesenem Zeichen angegeben */
while (str[i] == '<')
{
i++;
if (isdigit(str[i]))
{
j = 0;
while ((c = str[i++]) != '>')
{
/* solange nicht '>' */
czusatz[j++] = c;
}
czusatz[j] = NULL;
dzusatz = atof(czusatz);
qneu->zusatz = dzusatz;
}
else
{
if (isalpha(str[i]))
{
qneu->indice = str[i];
i += 2;
}
}
} /* Ende von '<>'-Bearbeitung */
}
else
{
/* ungueltige Produktion, da '=' fehlt */
p = NULL; /* damit wird Grammatik ungueltig */
return p;
}
}
break;
default: /* neues Symbol */
qneu = create_node(); /* neuer Symbolknoten */
q_end->next = qneu; /* Knoten an Liste anhaengen */
q_end = qneu;
qneu->symb = c; /* zugehoerige Werte */
/* falls '<' nach gelesenem Zeichen angegeben */
while (str[i] == '<')
{
i++;
if (isdigit(str[i]))
{
j = 0;
while ((c = str[i++]) != '>')
{
/* solange nicht '>' */
czusatz[j++] = c;
}
czusatz[j] = NULL;
dzusatz = atof(czusatz);
qneu->zusatz = dzusatz;
}
else
{
if (isalpha(str[i]))
{
qneu->indice = str[i];
i += 2;
}
}
} /* Ende von '<>'-Bearbeitung */
break;
} /* switch */
} /* while */
return p;
}
/*************************************************************************/
/* Function Name: count_char_word
* Description: bestimmt die Wortlaenge von symbollist
* Arguments: symbollist - Zeiger auf eine verkettete Liste mit Elementen
* vom Typ SYMBOLE
* Returns: laenge - Anzahl der char von symbollist
*/
int count_char_word(symbollist)
SYMBOLE *symbollist;
{
SYMBOLE *hilfe;
int laenge = 0;
hilfe = symbollist;
while (hilfe)
{
laenge ++;
hilfe = hilfe->next;
}
return laenge;
}
/*************************************************************************/
/* Function Name: word_to_string
* Description: kopiert die Symbole von list in einen char-String, wobei
* das Ableitungsende (deriv_end) bei einer symbolweisen
* Ableitung durch ein Blank im String gekennzeichnet wird
* Arguments: wordlist - Zeiger auf eine Liste von SYMBOLE
* deriv_end - Zeiger auf das Ableitungsende
* (innerhalb von list)
* Returns: zeichen - char-String
*/
char *word_to_string(wordlist, deriv_end)
SYMBOLE *wordlist,
*deriv_end;
{
int count_char_word();
SYMBOLE *hilfe;
char *zeichen;
int i;
i = count_char_word(wordlist);
zeichen = (char *)malloc(sizeof(char)*(6*i));
if (zeichen == NULL)
{
fprintf(stderr, "Kein Speicher mehr frei!\n");
fprintf(stderr, "malloc-Aufruf in word_to_string\n");
exit(1);
}
i = 0;
hilfe = wordlist;
while (hilfe)
{
/* markiert das Ende der Teilableitung */
if ((deriv_end != wordlist) && (hilfe == deriv_end))
{
zeichen[i++] = ' ';
}
zeichen[i++] = hilfe->symb;
/* falls Indice vorhanden */
if (hilfe->indice != ' ')
{
zeichen[i++] = '<';
zeichen[i++] = hilfe->indice;
zeichen[i++] = '>';
}
/* falls Zusatz ungleich 1 vorhanden */
if (hilfe->zusatz != 1)
{
zeichen[i++] = '<';
zeichen[i++] = '>';
}
hilfe = hilfe->next;
}
zeichen[i] = NULL;
return zeichen;
}
/*************************************************************************/
/* Function Name: test_dimens
* Description: Test, ob in der eingelesenen Grammatik nur 2D- oder
* auch 3D-Symbole enthalten sind
* Arguments: str_eingabe - enthaelt die Symbole
* Returns: dimens - 2: nur 2D-Symbole
* 3: auch 3D-Symbole
*/
int test_dimens(eingabe)
String eingabe;
{
String d3_symbole = "^&\/${}G,~!%";
int eingabe_laenge;
int dimens;
eingabe_laenge = strlen(eingabe);
if (strcspn(eingabe, d3_symbole) != eingabe_laenge)
{
dimens = 3;
}
else
{
dimens = 2;
}
return dimens;
}
/*************************************************************************/
/* Function Name: listlength
* Description: analog zu strlen wird die Laenge einer Liste bestimmt,
* d.h. es werden die Elemente vom Typ SYMBOLE gezaehlt
* Arguments: list - Pointer auf die Liste
* Returns: length - Laenge von list
*/
int listlength(list)
SYMBOLE *list;
{
int length = 0;
SYMBOLE *help = list;
while (help)
{
length ++;
help = help->next;
}
return length;
}
/*************************************************************************/
/* Function Name: delete_wordlist
* Description: gesamte list wird geloescht, slist ist anschl. NULL
* Arguments: slist - Zeiger auf eine verkettete Liste mit Elementen
* vom Typ SYMBOLE
* Returns: slist
*/
SYMBOLE *delete_wordlist(slist)
SYMBOLE *slist;
{
SYMBOLE *help;
help = slist;
slist = slist->next;
while (slist)
{
free(help);
help = slist;
slist = slist->next;
}
free(help);
slist = NULL;
return slist;
}
/*************************************************************************/
/* Function Name: delete_grammarlist
* Description: gesamte list wird geloescht, rlist ist anschl. NULL
* Arguments: rlist - Zeiger auf eine verkettete Liste mit Elementen
* vom Typ REGELN, wobei jeder Knoten auf eine
* Liste mit Elementen vom Typ SYMBOLE zeigen kann
* Returns: rlist
*/
REGELN *delete_grammarlist(rlist)
REGELN *rlist;
{
SYMBOLE *delete_wordlist();
REGELN *help;
help = rlist;
rlist = rlist->next;
while (rlist)
{
if (help->list)
{
/* rechte Seite der Produktion loeschen */
help->list = delete_wordlist(help->list);
}
/* linke Seite der Produktion loeschen */
free(help);
help = rlist;
rlist = rlist->next;
}
if (help->list)
{
help->list = delete_wordlist(help->list);
}
free(help);
rlist = NULL;
return rlist;
}
/*************************************************************************/
/* Function Name: klammerung
* Description: ueberprueft, ob in rlist die Klammern '[' und ']' bzw.
* '{' und '}' richtig gesetzt wurden. Die Ueberpruefung
* wird produktionsweise durchgefuehrt.
* Arguments: rlist - Zeiger auf eine verkettete Liste mit Elementen
* vom Typ REGELN, wobei jeder Knoten auf eine
* Liste mit Elementen vom Typ SYMBOLE zeigt
* Returns: fehler - 0: kein Fehler
* 1: Fehler bei Klammersetzung
*/
int klammerung(rlist)
REGELN *rlist;
{
REGELN *philfe;
SYMBOLE *qhilfe;
int i=0, /* zaehlt die gefundenen [ bzw. ] Klammern */
j=0; /* zaehlt die gefundenen { bzw. } Klammern */
int fehler=0; /* merkt sich aufgetretenen Fehler bei Klammersetzung */
philfe = rlist;
while (philfe)
{
qhilfe = philfe->list;
while (qhilfe)
{
switch(qhilfe->symb)
{
case '[': i++; /* neue oeffnende Klammer */
break;
case ']': i--; /* neue schliessende Klammer */
if (i<0) fehler = 1;
break;
case '{': j++; /* neue oeffnende Klammer */
if (j>1) fehler = 1;
break;
case '}': j--; /* neue schliessende Klammer */
if (j<0) fehler = 1;
break;
}
qhilfe = qhilfe->next;
}
if ((i!=0)||(j!=0)) fehler = 1;
philfe = philfe->next; /* naechste Produktion wird ueberprueft */
i=j=0;
}
return fehler;
}
/*************************************************************************/
/* Function Name: test_wk
* Description: ueberprueft, ob die Summe der angegebenen Wahrscheinlich-
* keiten bei den Produktionsregeln fuer gleiche Zeichen
* gleich 1 ist.
* Arguments: rlist
* Returns: fehler - 0: kein Fehler
* 20: Fehler
*/
int test_wk(rlist)
REGELN *rlist;
{
REGELN *philfe,
*prod;
double sum_wk = 0;
int fehler = 0;
philfe = rlist;
while (philfe)
{
if (philfe->zusatz != 1) /* oder in der Naehe ?? */
{
prod = rlist;
while (prod)
{
if ( (prod->symb == philfe->symb) &&
(prod->indice == philfe->indice) )
{
sum_wk += prod->zusatz;
}
prod = prod->next;
}
if (sum_wk != 1.0)
{
fehler = 20;
return fehler;
}
}
philfe = philfe->next;
sum_wk = 0;
}
return fehler;
}
/*************************************************************************/
/* Function Name: random_number
* Description: liefert eine Zufallszahl zwischen 0 und 1
* Returns: number - Zufallszahl
*/
double random_number()
{
static int i = 0;
double number;
int tt;
struct timeb tp;
if (i==0)
{
ftime(&tp);
tt = tp.millitm;
number = (double)srand(tt) / 10000;
number += (-(int)number);
i++;
}
else
{
number = rand();
number /= 10000;
number += (-(int)number);
}
return number;
}
/*************************************************************************/
/* Function Name:
* Description:
* Arguments:
* Globals:
* Returns:
*/
/************************************************************************/
/************************************************************************/